package com.io.smartappframe.mvc.activity

import android.content.Context
import android.graphics.ImageFormat
import android.hardware.camera2.*
import android.media.ImageReader
import android.os.*
import androidx.appcompat.app.AppCompatActivity
import android.view.SurfaceHolder
import android.view.View
import androidx.annotation.RequiresApi
import com.io.base.mvc.BaseActivityMVC
import com.io.commonlib.helper.LogHelper
import com.io.smartappframe.R
import com.io.smartappframe.databinding.ActivityCamera2Binding
import java.util.*

/**
 * Description:实现Camera2的相机预览
 * 2021-06-07 10:26
 * @author LiuMin
 */
class Camera2Activity : BaseActivityMVC<ActivityCamera2Binding>(), View.OnClickListener,
    ImageReader.OnImageAvailableListener {

    private var mCameraManager: CameraManager? = null
    private var childHandler: Handler? = null
    private var mainHandler: Handler? = null
    private var mCameraDevice: CameraDevice? = null
    private var mSurfaceHolder: SurfaceHolder? = null
    private var mPreviewBuilder: CaptureRequest.Builder? = null
    private var mSession: CameraCaptureSession? = null
    private var mImageReader: ImageReader? = null

    private var handlerThread = HandlerThread("Camera2")

    override fun initView(savedInstanceState: Bundle?): ActivityCamera2Binding {
        return ActivityCamera2Binding.inflate(layoutInflater)
    }

    override fun initData(savedInstanceState: Bundle?) {
        mViewBinding.header.tvTitle.setText("预览Camera2图像")
        mViewBinding.header.ivToolbarBack.setOnClickListener(this)
        mViewBinding.btnStart.setOnClickListener(this)
        mViewBinding.btnStop.setOnClickListener(this)
        mSurfaceHolder = mViewBinding.surfaceView.holder
        mSurfaceHolder?.setKeepScreenOn(true)
        handlerThread.start()
        childHandler = Handler(handlerThread.looper)
        mainHandler = Handler(mainLooper)
        mCameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
        mSurfaceHolder?.addCallback(object : SurfaceHolder.Callback {
            override fun surfaceCreated(holder: SurfaceHolder) {
                LogHelper.d(TAG, "surfaceCreated--")
            }

            override fun surfaceChanged(
                holder: SurfaceHolder,
                format: Int,
                width: Int,
                height: Int
            ) {
                LogHelper.d(TAG, "surfaceChanged--")
            }

            override fun surfaceDestroyed(holder: SurfaceHolder) {
                LogHelper.d(TAG, "surfaceDestroyed--")
                if (mCameraDevice != null) {
                    mCameraDevice?.close()
                    mCameraDevice = null
                }
            }
        })
        mImageReader = ImageReader.newInstance(1080, 2340, ImageFormat.JPEG, 2)
        mImageReader?.setOnImageAvailableListener(this, mainHandler)
    }

    override fun onClick(v: View?) {
        v?.let {
            if (it.id == R.id.iv_toolbar_back) {
                finish()
            } else if (it.id == R.id.btnStart) {
                clickStart()
            } else if (it.id == R.id.btnStop) {
                if (mCameraDevice != null) {
                    mCameraDevice?.close()
                    mCameraDevice = null
                }
            }
        }
    }

    private fun clickStart() {
        mCameraManager?.let {
            val cameraIdList = it.cameraIdList
            it.openCamera(cameraIdList[0], object : CameraDevice.StateCallback() {
                override fun onOpened(camera: CameraDevice) {
                    //开启预览
                    mCameraDevice = camera
                    mCameraDevice?.let {
                        startPreview(it)
                    }
                }

                override fun onDisconnected(camera: CameraDevice) {
                    if (mCameraDevice != null) {
                        mCameraDevice?.close()
                        mCameraDevice = null
                    }
                }

                override fun onError(camera: CameraDevice, error: Int) {

                }
            }, mainHandler)
        }

    }

    override fun onDestroy() {
        super.onDestroy()
        if (mCameraDevice != null) {
            mCameraDevice?.close()
            mCameraDevice = null
        }
    }

    //开始预览
    private fun startPreview(camera: CameraDevice) {
        //创建预览需要的CaptureRequest.Builder
        mPreviewBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
        mPreviewBuilder?.let { it ->
            mSurfaceHolder?.let { it0 ->
                // 将SurfaceView的surface作为CaptureRequest.Builder的目标
                it.addTarget(it0.surface)
                //自动对焦
                it.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE)
                it.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF)
                //设置拍摄图像时相机设备是否使用光学防抖
                it.set(
                    CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE,
                    CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_ON
                )
                //感光灵敏度
                it.set(CaptureRequest.SENSOR_SENSITIVITY, 1600)
                //曝光补偿
                it.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0)
                //创建CameraCaptureSession，该对象负责管理处理预览请求和拍照请求
                mCameraDevice?.createCaptureSession(
                    Arrays.asList(
                        it0.surface,
                        mImageReader?.surface
                    ), mSessionStateCallback, childHandler
                )
            }
        }

    }

    private val mSessionStateCallback: CameraCaptureSession.StateCallback =
        object : CameraCaptureSession.StateCallback() {
            override fun onConfigured(session: CameraCaptureSession) {
                mSession = session
                if (mCameraDevice != null && mPreviewBuilder == null) {
                    try {
                        mPreviewBuilder =
                            mCameraDevice?.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)
                        // 将imageReader的surface作为CaptureRequest.Builder的目标
                        mImageReader?.let {
                            mPreviewBuilder?.addTarget(it.getSurface())
                        }
                        //关闭自动对焦
                        mPreviewBuilder?.set(
                            CaptureRequest.CONTROL_AF_MODE,
                            CaptureRequest.CONTROL_AF_MODE_OFF
                        )
                        mPreviewBuilder?.set(
                            CaptureRequest.CONTROL_AE_MODE,
                            CaptureRequest.CONTROL_AE_MODE_OFF
                        )
                        //设置拍摄图像时相机设备是否使用光学防抖（OIS）。
                        mPreviewBuilder?.set(
                            CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE,
                            CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_ON
                        )
                        mPreviewBuilder?.set(CaptureRequest.SENSOR_SENSITIVITY, 1600)
                        //曝光补偿//
                        mPreviewBuilder?.set(
                            CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION,
                            0
                        )
                    } catch (e: CameraAccessException) {
                        e.printStackTrace()
                    }
                }
                try {
                    updatePreview(session)
                } catch (e: CameraAccessException) {
                    e.printStackTrace()
                }
            }

            override fun onConfigureFailed(session: CameraCaptureSession) {}
        }


    private fun updatePreview(session: CameraCaptureSession) {
        mPreviewBuilder?.let {
            session.setRepeatingRequest(it.build(), mCaptureCallback, childHandler)
        }
    }

    private val mCaptureCallback: CameraCaptureSession.CaptureCallback =
        object : CameraCaptureSession.CaptureCallback(){
            override fun onCaptureCompleted(
                session: CameraCaptureSession,
                request: CaptureRequest,
                result: TotalCaptureResult
            ) {
                super.onCaptureCompleted(session, request, result)
                //需要连拍时，循环保存图片就可以了
            }
        }

    override fun onImageAvailable(reader: ImageReader?) {
        LogHelper.d(TAG, "onImageAvailable--")
    }


}